package game.damageSystem;
import java.io.Serializable;
import java.util.TreeMap;
import java.util.Vector;

import physics.Body;
import physics.collision.Arbiter;
import physics.sleeping.Connection;
import tools.Help;
import tools.Log;
import game.Game;
import game.objects.GameObject;
import game.objects.interfaces.Damageable;
public class DamageSystem implements Serializable {
	private static final float MINENERGY = 500;
	private static final float MINIMPULSE = 0;
	private static final float MINVELOCITY = 700;
	private static final float MAXENERGY = 5000;
	private static final float MAXIMPULSE = 2500;
	private static final float MAXVELOCITY = 6000;
	private Game game;
	private TreeMap<Integer, Float> hps;
	private Vector<Damageable> destoyObjects;
	public DamageSystem(Game g) {
		this.game = g;
		hps = new TreeMap<Integer, Float>();
		destoyObjects = new Vector<Damageable>();
	}
	public void handle() {
		destoyObjects.clear();
		for (int i = 0; i < game.numGameObjects; i++) {
			GameObject o = game.getGameObject(i);
			if (o instanceof Damageable) {
				Damageable d = (Damageable) o;
				Body b;
				for (int j = 0; j < o.numBodies; j++) {
					b = o.getBody(j);
					// for (Connection c : b.connections){
					for (int ic = 0; ic < b.connections.size(); ic++) {
						Connection c = b.connections.get(ic);
						if (c.joint instanceof Arbiter) {
							Arbiter a = (Arbiter) c.joint;
							float e = a.energy;
							float p = a.impulse;
							float v = a.relVel;
							handleCollision(d, o.id, e, p, v);
						}
					}
				}
			}
		}
		for (Damageable d : this.destoyObjects) {
			d.destroy();
		}
	}
	private void handleCollision(Damageable d, int id, float energy, float impulse, float velocity) {
		if (energy < MINENERGY)
			return;
		if (impulse < MINIMPULSE)
			return;
		if (velocity < MINVELOCITY)
			return;
		float damage = energy / MAXENERGY * impulse / MAXIMPULSE * velocity / MAXVELOCITY;
		damageObject(id, damage);
		if (lifeLeft(id) < 0) {
			// d.destroy();
			this.destoyObjects.add(d);
		}
	}
	private void damageObject(int id, float damage) {
		if (!hps.containsKey(id))
			hps.put(id, 1.0f); // Object has not been added yet. Start with full health.
		hps.put(id, hps.get(id) - damage);
		Log.g(id + " " + damage);
	}
	private float lifeLeft(int id) {
		return hps.get(id);
	}
}
